/*
 * Copyright (C) 2018 Zhejiang xiaominfo Technology CO.,LTD.
 * All rights reserved.
 * Official Web Site: http://www.xiaominfo.com.
 * Developer Web Site: http://open.xiaominfo.com.
 */

package com.github.xiaoymin.gateway.spring.configuration;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.github.xiaoymin.gateway.core.RouteCache;
import com.github.xiaoymin.gateway.core.RouteDispatcher;
import com.github.xiaoymin.gateway.core.RouteRepository;
import com.github.xiaoymin.gateway.core.auth.DefaultServletGatewayAuthentication;
import com.github.xiaoymin.gateway.core.auth.ServletGatewayAuthentication;
import com.github.xiaoymin.gateway.core.cache.RouteInMemoryCache;
import com.github.xiaoymin.gateway.core.common.ExecutorEnum;
import com.github.xiaoymin.gateway.core.filter.ServletGatewayRouteProxyFilter;
import com.github.xiaoymin.gateway.core.pojo.ServiceRoute;
import com.github.xiaoymin.gateway.repository.CloudRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

/**
 * @author <a href="mailto:xiaoymin@foxmail.com">xiaoymin@foxmail.com</a>
 * 2020/11/13 13:12
 * @since:servlet-gateway-spring-boot-starter 1.0
 */
@Configuration
@EnableConfigurationProperties({ServletGatewayProperties.class})
@ConditionalOnProperty(name = "server.servlet.gateway.enable",havingValue = "true")
public class ServletGatewayAutoConfiguration {

    final Environment environment;

    @Autowired
    public ServletGatewayAutoConfiguration(Environment environment) {
        this.environment = environment;
    }

    @Bean
    public RouteCache<String, ServiceRoute> routeCache(){
        return new RouteInMemoryCache();
    }

    @Bean
    @ConditionalOnProperty(name = "server.servlet.gateway.cloud.enable",havingValue = "true")
    public CloudRepository cloudRepository(@Autowired ServletGatewayProperties servletGatewayProperties){
        return new CloudRepository(servletGatewayProperties.getCloud());
    }

    @Bean
    public RouteDispatcher routeDispatcher(@Autowired RouteRepository routeRepository,
                                           @Autowired RouteCache<String, ServiceRoute> routeCache){
        //获取当前项目的contextPath
        String contextPath=environment.getProperty("server.servlet.context-path");
        if (StrUtil.isBlank(contextPath)){
            contextPath="/";
        }
        if (StrUtil.isNotBlank(contextPath)&&!StrUtil.equals(contextPath,RouteDispatcher.ROUTE_BASE_PATH)){
            //判断是否/开头
            if (!StrUtil.startWith(contextPath,RouteDispatcher.ROUTE_BASE_PATH)){
                contextPath=RouteDispatcher.ROUTE_BASE_PATH+contextPath;
            }
        }
        return new RouteDispatcher(routeRepository,routeCache, ExecutorEnum.APACHE,contextPath);
    }

    /**
     * 注入一个默认的权限
     * @return defaultAuth
     */
    @Bean
    @ConditionalOnMissingBean
    public DefaultServletGatewayAuthentication servletGatewayAuthentication(){
        return new DefaultServletGatewayAuthentication();
    }

    /**
     * Spring容器中注入ServletGatewayRouteProxyFilter的实体Bean
     * @param routeDispatcher 执行器
     * @param servletGatewayAuthentication 权限校验对象实例
     * @return ServletGatewayRouteProxyFilter的实体Bean
     */
    @Bean
    @ConditionalOnMissingBean
    public ServletGatewayRouteProxyFilter servletGatewayRouteProxyFilter(@Autowired RouteDispatcher routeDispatcher, @Autowired ServletGatewayAuthentication servletGatewayAuthentication){
        return new ServletGatewayRouteProxyFilter(routeDispatcher, servletGatewayAuthentication);
    }

    @Bean
    public FilterRegistrationBean routeProxyFilter(@Autowired ServletGatewayRouteProxyFilter servletGatewayRouteProxyFilter,@Autowired ServletGatewayProperties servletGatewayProperties)
    {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(servletGatewayRouteProxyFilter);
        filterRegistrationBean.setOrder(99);
        filterRegistrationBean.setEnabled(true);
        if (CollectionUtil.isNotEmpty(servletGatewayProperties.getUrlPatterns())){
            filterRegistrationBean.addUrlPatterns(servletGatewayProperties.getUrlPatterns().toArray(new String[]{}));
        }else{
            //默认扫描所有,如果客户端不配置的情况下
            filterRegistrationBean.addUrlPatterns("/*");
        }
        return filterRegistrationBean;
    }
}
